package xyz.cerberu.cet.shiro.configuration;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.AbstractRememberMeManager;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.mgt.WebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import xyz.cerberu.cet.shiro.dao.SessionRedisDao;
import xyz.cerberu.cet.shiro.filter.RedisRememberMeManager;
import xyz.cerberu.cet.shiro.realm.UserRealm;

import javax.servlet.Filter;
import java.util.HashMap;

/**
 * @author β世界
 * Created on 10:27
 * @Description shiro的配置文件
 */
@Configuration
public class ShiroConfig {

    /**
     * @author β世界 on 13:04 2021/3/4
     * 配置Shiro的过滤器
     * @return org.apache.shiro.spring.web.ShiroFilterFactoryBean
     **/
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultSecurityManager defaultSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(defaultSecurityManager);
        // 配置过滤器
        HashMap<String,Filter> filterMap = new HashMap<>();



        return shiroFilterFactoryBean;
    }


    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public AbstractRememberMeManager rememberMeManager(){
        return new RedisRememberMeManager();
    }

    @Bean
    public UserRealm userRealm(){
        UserRealm userRealm = new UserRealm();
        // 设置加密的方式
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
        hashedCredentialsMatcher.setHashIterations(1);
        userRealm.setCredentialsMatcher(hashedCredentialsMatcher);
        return userRealm;
    }

    @Bean
    public DefaultWebSessionManager defaultWebSessionManager(SessionRedisDao sessionRedisDao){
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        // 设置session的dao为我们自己定义的
        sessionManager.setSessionDAO(sessionRedisDao);
        return sessionManager;
    }

    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(CacheManager memoryConstrainedCacheManager,AbstractRememberMeManager rememberMeManager,UserRealm userRealm,DefaultWebSessionManager defaultWebSessionManager){
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        // 设置记住密码的管理方式
        manager.setRememberMeManager(rememberMeManager);
        // 设置用户的基本加密和管理设置
        manager.setRealm(userRealm);
        manager.setCacheManager(memoryConstrainedCacheManager);
        return manager;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(WebSecurityManager defaultWebSecurityManager){
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        // 添加主要的web安全管理器
        advisor.setSecurityManager(defaultWebSecurityManager);
        return advisor;
    }

    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }

    @Bean
    public CacheManager memoryConstrainedCacheManager(){
        return new MemoryConstrainedCacheManager();
    }

}
